<template>
  <v-dialog v-model="dialogVisible" :persistent="true" max-width="450px" @click:outside="close"
    class="role-management-perms">
    <v-card>
      <v-card-title>{{ dialogTitle }}</v-card-title>

      <v-card-text>
        <v-text-field v-model="filterText" placeholder="输入关键字过滤" density="compact" variant="outlined" hide-details
          prepend-inner-icon="mdi-magnify" class="mb-4" />

        <v-list class="perms-list" density="compact">
          <!-- 递归渲染权限项 -->
          <template v-for="item in filteredPermsData" :key="item.id">
            <PermsListItem :item="item" :level="0" :selected-ids="selectedIds" :expanded-nodes="expandedNodes"
              @toggle-select="toggleSelect" @toggle-expand="toggleExpand" />
          </template>

          <!-- 加载状态 -->
          <v-list-item v-if="loading">
            <v-list-item-title>
              <v-progress-circular indeterminate size="16" class="mr-2" />
              加载中...
            </v-list-item-title>
          </v-list-item>

          <!-- 无数据状态 -->
          <v-list-item v-if="!loading && filteredPermsData.length === 0">
            <v-list-item-title class="text-grey">
              {{ filterText ? '无匹配数据' : '暂无权限数据' }}
            </v-list-item-title>
          </v-list-item>
        </v-list>
      </v-card-text>

      <v-card-actions>
        <v-spacer />
        <v-btn color="grey-darken-1" variant="text" @click="close">
          取消
        </v-btn>
        <v-btn color="primary" variant="text" @click="save">
          确定
        </v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { isNull } from "@/utils/validate";
import { getMenuAndPermsTree } from "@/api/system/menu/menuManagement";
import { doGetPerms, doSetPerms } from "@/api/system/role/roleManagement";
import { useMessage } from "@/composables/useMessage";
import PermsListItem from './PermsListItem.vue';

interface PermsNode {
  id: string;
  name: string;
  type: string;
  children?: PermsNode[];
  [key: string]: any;
}

const { success: showSuccess } = useMessage();

// 响应式数据
const activeName = ref('');
const roleId = ref('');
const permsData = ref<PermsNode[]>([]);
const filterText = ref('');
const selectedIds = ref<Set<string>>(new Set());
const expandedNodes = ref<Set<string>>(new Set());
const dialogTitle = ref('设置权限');
const dialogVisible = ref(false);
const loading = ref(false);

// 过滤后的权限数据
const filteredPermsData = computed(() => {
  if (!filterText.value) return permsData.value;

  const filterNodes = (nodes: PermsNode[]): PermsNode[] => {
    return nodes.filter(node => {
      const matchesFilter = node.name?.toLowerCase().includes(filterText.value.toLowerCase());
      const hasMatchingChildren = node.children ? filterNodes(node.children).length > 0 : false;

      if (matchesFilter || hasMatchingChildren) {
        return {
          ...node,
          children: node.children ? filterNodes(node.children) : undefined
        };
      }
      return false;
    }).map(node => typeof node === 'object' ? node : null).filter(Boolean) as PermsNode[];
  };

  return filterNodes(permsData.value);
});

// 获取图标
function getIcon(type: string) {
  switch (type) {
    case '1': return 'mdi-view-dashboard';
    case '2': return 'mdi-cog';
    case '3': return 'mdi-link';
    default: return 'mdi-file-document-outline';
  }
}

// 显示权限设置对话框
function showPerms(row: any, activeNameValue: string) {
  dialogVisible.value = true;
  roleId.value = row.id;
  activeName.value = activeNameValue;
  selectedIds.value.clear();
  expandedNodes.value.clear();
  fetchData();
}

// 关闭对话框
function close() {
  dialogVisible.value = false;
  roleId.value = '';
  activeName.value = '';
  permsData.value = [];
  selectedIds.value.clear();
  expandedNodes.value.clear();
  filterText.value = '';
}

// 保存权限设置
async function save() {
  try {
    const nodeIds = Array.from(selectedIds.value);
    const response = await doSetPerms({
      roleId: roleId.value,
      permsIds: unique(nodeIds)
    });
    showSuccess(response.data?.msg || "设置成功");
    close();
  } catch (error) {
    console.error(error);
  }
}

// 获取权限数据
async function fetchData() {
  loading.value = true;
  try {
    const [{ data }, checkedData] = await Promise.all([
      getMenuAndPermsTree({ label: activeName.value }),
      doGetPerms({ roleId: roleId.value })
    ]);

    permsData.value = data || [];
    console.log(permsData.value);

    if (!isNull(checkedData.data) && !isNull(checkedData.data)) {
      const checkArray = checkedData.data;
      if (checkArray && checkArray.length > 0) {
        // 将已选中的权限ID添加到selectedIds中
        checkArray.forEach((id: string) => {
          selectedIds.value.add(id);
        });
      }
    }
  } catch (error) {
    console.error(error);
  } finally {
    loading.value = false;
  }
}

// 切换选择状态
function toggleSelect(nodeId: string, isSelected: boolean) {
  if (isSelected) {
    selectedIds.value.add(nodeId);
  } else {
    selectedIds.value.delete(nodeId);
  }
}

// 切换展开状态
function toggleExpand(nodeId: string) {
  if (expandedNodes.value.has(nodeId)) {
    expandedNodes.value.delete(nodeId);
  } else {
    expandedNodes.value.add(nodeId);
  }
}

// 数组去重
function unique(arr: string[]): string[] {
  return Array.from(new Set(arr));
}

// 暴露方法给父组件
defineExpose({
  showPerms
});
</script>

<style lang="scss" scoped>
.role-management-perms {
  .perms-list {
    max-height: 400px;
    overflow-y: auto;
    border: 1px solid rgba(0, 0, 0, 0.12);
    border-radius: 4px;
  }
}
</style>
